/**
 * @(#)TerminMapper.java
 * 1.0, 2013-01-24
 */
package de.hdm.gruppenkalender.team04.db;

import de.hdm.gruppenkalender.team04.data.*;
import java.rmi.RemoteException;
import java.sql.*;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

// <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
// #[regen=yes,id=DCE.F441638C-C755-D80E-798A-4DA7F61224DE]
// </editor-fold>
/**
 * Mapper-Klasse, die {@link Termin}-Objekte auf eine relationale
 * Datenbank abbildet.
 * <p>
 * Hierzu wird eine Reihe von Methoden zur Verfügung gestellt, mit deren Hilfe
 * z.B. Objekte gesucht, erzeugt, modifiziert und gelöscht werden können.
 * <p>
 * In Anlehung an:
 * de.hdm.thies.bankprojekt.db.AccountMapper
 *
 * @author Prof. Dr. Peter Thies
 *
 * @author Mathias Bendel (mb167)
 * @author Björn Fichnter (bf023)
 * @author Stefan Hettich (sh176)
 * @author René Kugel (rk044)
 * @author Mark Leonberger (ml072)
 * @author Marta Przybylski (mp070)
 *
 * @version 1.0, 2013-01-24
 *
 */
public class TerminMapper {

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.EC522FC5-1333-E953-5263-8D5824523EB5]
    // </editor-fold>
    /**
     * Die Klasse TerminMapper wird nur einmal instantiiert. Man spricht hierbei
     * von einem sogenannten <b>Singleton</b>.
     * <p>
     * Diese Variable ist durch den Bezeichner <code>static</code> nur einmal für
     * sämtliche eventuellen Instanzen dieser Klasse vorhanden. Sie speichert die
     * einzige Instanz dieser Klasse.
     *
     * @see #terminMapper()
     */
    private static TerminMapper terminMapper;

    /**
     * Geschützter Konstruktor - verhindert die Möglichkeit, mit new neue
     * Instanzen dieser Klasse zu erzeugen.
     */
    protected TerminMapper() {
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.4FDA1FF0-2EBC-6A2B-72CF-E38754A7AEC4]
    // </editor-fold>
    /**
     * Diese statische Methode kann aufgrufen werden durch
     * <code>TerminMapper.terminMapper()</code>. Sie stellt die
     * Singleton-Eigenschaft sicher, indem Sie dafür sorgt, daß nur eine einzige
     * Instanz von <code>TerminMapper</code> existiert.
     *
     * @return {@link TerminMapper}-Objekt.
     * @see #terminMapper
     */
    public static TerminMapper terminMapper() {
        if (terminMapper == null) {
            terminMapper = new TerminMapper();
        }
        return terminMapper;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.DDDE14D6-0075-B105-1085-ECB69AE247F1]
    // </editor-fold>
    /**
     * Gibt ein Objekt mit übergegebener Id zurück.
     *
     * @param   id
     * @return  Termin {@link Termin}-Objekt, oder null wenn keines gefunden wurde.
     */
    public Termin findeViaSchluessel(int id) {
        // DB-Verbindung holen
        Connection con = DBVerbindung.connection();

        try {
            // Leeres SQL-Statement (JDBC) anlegen
            Statement stmt = con.createStatement();

            ResultSet rs = stmt.executeQuery(
                    "SELECT terminId, folgeterminId FROM termin " +
                    " WHERE terminId =" + id + ";");

            if (rs.next()) {
                Termin t = new TerminImpl();
                t.setId(rs.getInt("terminId"));
                t.setFolgeterminId(rs.getInt("folgeterminId"));

                con.close();

                System.out.println(TerminMapper.class.getName() +
                        " - findeViaSchluessel ausgeführt.");

                return t;
            }
        } catch (RemoteException ex) {
            Logger.getLogger(TerminMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(TerminMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
        return null;
    }

    /**
     * Gibt ein {@link Termin}-Objekten zurück,
     * die der übergebenen Folge-{@link Termin}-Id zugeordnet ist zurück.
     *
     * @param   folgeterminId
     * @return  Termin {@link Termin} mit übergebener Folge-{@link Termin}-Id.
     */
    public Termin findeViaFolgetermin(int folgeterminId) {
        // DB-Verbindung holen
        Connection con = DBVerbindung.connection();

        try {
            // Leeres SQL-Statement (JDBC) anlegen
            Statement stmt = con.createStatement();

            // Statement ausfüllen und als Query an die DB schicken
            ResultSet rs = stmt.executeQuery(
                    "SELECT terminId, folgeterminId FROM termin " +
                    " WHERE folgeterminId =" + folgeterminId + ";");

            // Statement ausfüllen und als Query an die DB schicken
            if (rs.next()) {
                // Umwandlung in ein {@link Termin}-Objekt.
                Termin t = new TerminImpl();
                t.setId(rs.getInt("terminId"));
                t.setFolgeterminId(rs.getInt("folgeterminId"));

                con.close();

                System.out.println(TerminMapper.class.getName() +
                        " - findeViaFolgetermin ausgeführt.");

                return t;
            }
        } catch (RemoteException ex) {
            Logger.getLogger(TerminMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(TerminMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
        return null;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.A8E5F4CB-EC80-63CF-2B5B-516B58CF600E]
    // </editor-fold>
    /**
     * Auslesen aller {@link Termin}-Objekte.
     *
     * @return  Vector<Termin> Ein {@link Vector} mit {@link Termin}-Objekten.
     */
    public Vector<Termin> findeAlle() {
        // DB-Verbindung holen
        Connection con = DBVerbindung.connection();

        Vector<Termin> result = new Vector<Termin>();

        try {
            // Leeres SQL-Statement (JDBC) anlegen
            Statement stmt = con.createStatement();

            // Statement ausfüllen und als Query an die DB schicken
            ResultSet rs = stmt.executeQuery(
                    "SELECT terminId, folgeterminId FROM termin " +
                    " ORDER BY terminId");

            /**
             * Für jeden Eintrag im Suchergebnis wird nun
             * ein {@link Termin}-Objekt erstellt.
             */
            while (rs.next()) {
                Termin t = new TerminImpl();
                t.setId(rs.getInt("terminId"));
                t.setFolgeterminId(rs.getInt("folgeterminId"));
                result.addElement(t);
            }

            con.close();

            System.out.println(TerminMapper.class.getName() +
                    " - findeAlle ausgeführt.");

            return result;

        } catch (RemoteException ex) {
            Logger.getLogger(TerminMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(TerminMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
        return null;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.0D67B619-F737-3382-EA74-D6405B116D8E]
    // </editor-fold>
    /**
     * Einfügen eins {@link Termin}-Objekts in die Datenbank.
     *
     * @param   t   das zu speichernde Objekt
     * @return  das gespeicherte Objekt.
     */
    public Termin einfuegen(Termin t) {
        // DB-Verbindung holen
        Connection con = DBVerbindung.connection();

        try {
            // Leeres SQL-Statement (JDBC) anlegen
            Statement stmt = con.createStatement();

            // Statement ausfüllen und als Query an die DB schicken
            stmt.executeUpdate(
                    "INSERT INTO termin (terminId, folgeterminId) " +
                    "VALUES ('" +
                    t.getId() + "'," +
                    (t.getFolgeterminId() == 0 ? "NULL" : "'" +
                    t.getFolgeterminId() + "'") +
                    ");");

            con.close();

            System.out.println(TerminMapper.class.getName() +
                    " - einfuegen ausgeführt.");

            return t;

        } catch (RemoteException ex) {
            Logger.getLogger(TerminMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(TerminMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
        return null;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.179D1418-AF31-A144-50D6-F3859626ED8E]
    // </editor-fold>
    /**
     * Wiederholtes Schreiben eines Objekts in die Datenbank.
     *
     * @param   t   das Objekt, das in die DB geschrieben werden soll
     * @return  das als Parameter übergebene Objekt
     */
    public Termin aktualisieren(Termin t) {
        // DB-Verbindung holen
        Connection con = DBVerbindung.connection();

        try {
            // Leeres SQL-Statement (JDBC) anlegen
            Statement stmt = con.createStatement();

            // Statement ausfüllen und als Query an die DB schicken
            stmt.executeUpdate("UPDATE termin " +
                    "SET folgeterminId='" +
                    t.getFolgeterminId() + "' WHERE terminId=" +
                    t.getId());

            con.close();

            System.out.println(TerminMapper.class.getName() +
                    " - aktualisieren ausgeführt.");

            return t;

        } catch (RemoteException ex) {
            Logger.getLogger(TerminMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(TerminMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
        return null;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.0B7D530F-01EF-47EF-AFF0-9902DA3F9285]
    // </editor-fold>
    /**
     * Löschen der Daten eines {@link Termin}-Objekts aus der Datenbank.
     *
     * @param   id  des aus der DB zu löschenden "Objekts".
     */
    public void loeschen(int id) {
        // DB-Verbindung holen
        Connection con = DBVerbindung.connection();

        try {
            // Leeres SQL-Statement (JDBC) anlegen
            Statement stmt = con.createStatement();

            // Statement ausfüllen und als Query an die DB schicken
            stmt.executeUpdate("DELETE FROM termin " +
                    "WHERE terminId=" + id);

            con.close();

            System.out.println(TerminMapper.class.getName() +
                    " - loeschen ausgeführt.");

        } catch (SQLException ex) {
            Logger.getLogger(TerminMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Löschen der Daten eines {@link Termin}-Objekts aus der Datenbank.
     *
     * @param   t  das aus der DB zu löschende "Objekt".
     */
    public void loeschen(Termin t) {
        try {
            this.loeschen(t.getId());
        } catch (RemoteException ex) {
            Logger.getLogger(TerminMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
    }
}
